﻿using SimpleCrawler.DAL;
using SimpleCrawler.DependencyInjection;
using SimpleCrawler.Entity;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using System.Threading;

namespace SimpleCrawler.Crawler
{
    public class SinaIAskCrawler : CrawlerBase
    {    
        //private ILog logger;    
        CrawlerDAL dal;
        public SinaIAskCrawler():base(1007,"Sina爱问") {
            //logger = LoggerManager.GetLogger(GetType());
            dal = AppServiceProvider.ServiceProvider.GetService<CrawlerDAL>();
        }

        public override Task<string> GetTargetHtmlString()
        {
            return base.GetTargetHtmlString();
        }

        public override void GetStartedPageUrl()
        {        
            RequestUrl = $"https://iask.sina.com.cn/search?searchWord={System.Web.HttpUtility.UrlEncode(CrawlerTask.KeyWord)}&page=1";           
        }
        public override void GetNextPageUrl(int page)
        {
            RequestUrl = $"https://iask.sina.com.cn/search?searchWord={System.Web.HttpUtility.UrlEncode(CrawlerTask.KeyWord)}&page={page}";
        }

        //https://iask.sina.com.cn/b/6hxsmtPhCOP.html 
        public async override Task<int> GetResultContent(string html)
        {
            Match table = Regex.Match(html, @"search-list[\s\S]*?<ul>[\s\S]*?</ul>");
            MatchCollection trlist = Regex.Matches(table.ToString(), @"<li>[\s\S]*?</li>");
            Regex realUrlReg = new Regex(@"<a href=""([\s\S]*?)""[\s\S]*?>([\s\S]*?)</a>[\s\S]*?mr18"">(\d{4}-\d{1,2}-\d{1,2})</span>");

            //Regex quetionReg = new Regex(@"<div class=""mod-q js-form""[\s\S]*?title js-ask-title"">([\s\S]*?)</h2>[\s\S]*?<span>被浏览(\d*)次[\s\S]*?<span>(\d{4}-\d{2}-\d{2}|\d{4}.\d{2}.\d{2})</span>");
            Regex bestAnswer = new Regex(@"class=""good_answer""[\s\S]*?(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})</span>[\s\S]*?praise mr15[\s\S]*?<span>(\d*)</span>[\s\S]*?praise1 mr15[\s\S]*?<span>(\d*)</span>[\s\S]*?answer_text[\s\S]*?<pre>([\s\S]*?)</pre>");

            Regex otherAnswers = new Regex(@"<div class=""answer_list[\s\S]*?huasheng_page");
            Regex otherAnswer = new Regex(@"<li  t=""disploy"">[\s\S]*?iask-comment-ele");

            Regex content = new Regex(@"<pre>([\s\S]*?)</pre>");
            Regex left = new Regex(@"class=""answer_t""[\s\S]*?(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})</span>[\s\S]*?praise mr15[\s\S]*?<span>(\d*)</span>[\s\S]*?praise1 mr15[\s\S]*?<span>(\d*)</span>");

            List <WD_Question> questions = new List<WD_Question>();
            if (trlist.Count > 0)
            {
                foreach (var tr in trlist)
                {
                    Match MrealUrl = realUrlReg.Match(tr.ToString());
                    if (MrealUrl.Success)
                    {
                        WD_Question question = new WD_Question();
                        string url = "https://iask.sina.com.cn" + MrealUrl.Groups[1].ToString().Trim();
                        //url过滤
                        if (Filter != null && Filter.Contains(url))
                        {
                            Logger.Error($"已过滤的问答,link=>{url}");
                            FilterCount++;
                            continue;
                        }
                        Filter.Add(url);
                        //
                        string detailHtml = await SendRequestByGet(url);
                        Thread.Sleep(10 * 1000);
                        try
                        {
                            question.SourceSite = this.CrawlerID;
                            question.KeyWord = this.CrawlerTask.KeyWord;
                            question.SourceUrl = url;
                            question.Question = CleanTag( MrealUrl.Groups[2].ToString()).Replace("\"","");
                            question.CreateTime = DateTime.Parse(MrealUrl.Groups[3].ToString());
                        }
                        catch (Exception ex)
                        {
                            Logger.Error($"问题匹配出错,link=>{RequestUrl} {ex.ToString()}");
                        }
                        if (string.IsNullOrEmpty(question.Question) || question.CreateTime == null)
                            continue;

                        question.Answers = new List<WD_Answer>();
                        Match MbestAnswer = bestAnswer.Match(detailHtml);
                        if (MbestAnswer.Success)
                        {
                            WD_Answer answer = new WD_Answer();
                            try
                            {
                                answer.IsAdopt = 1;
                                answer.Answer = MbestAnswer.Groups[4].ToString();
                                answer.AnswerLen = answer.Answer.Length;
                                answer.CreateDate = DateTime.Parse(MbestAnswer.Groups[1].ToString());
                                answer.ZanCount = int.Parse(MbestAnswer.Groups[2].ToString());
                                answer.CaiCount = int.Parse(MbestAnswer.Groups[3].ToString());
                            }
                            catch (Exception ex)
                            {
                                Logger.Error($"最佳答案匹配出错,link=>{url} {ex.ToString()}");
                            }
                            if (!string.IsNullOrEmpty(answer.Answer))
                            {
                                question.Answers.Add(answer);
                            }
                        }

                        MatchCollection MotherAnswers = otherAnswer.Matches(otherAnswers.Match(detailHtml).ToString());
                        foreach (Match item in MotherAnswers)
                        {
                            WD_Answer answer = new WD_Answer();
                            try
                            {
                                MatchCollection Mcontents=content.Matches(item.ToString());
                                if (Mcontents.Count == 1)
                                {
                                    answer.Answer = Mcontents[0].Groups[1].ToString();
                                }
                                else if (Mcontents.Count > 1)
                                {
                                    answer.Answer = Mcontents[1].Groups[1].ToString();
                                }
                                else
                                {
                                    answer.Answer =string.Empty;
                                }
                                answer.AnswerLen = answer.Answer.Length;
                                Match Mleft = left.Match(item.ToString());
                                answer.CreateDate = DateTime.Parse(Mleft.Groups[1].ToString());
                                answer.ZanCount = int.Parse(Mleft.Groups[2].ToString());
                                answer.CaiCount = int.Parse(Mleft.Groups[3].ToString());
                            }
                            catch (Exception ex)
                            {
                                Logger.Error($"其他答案匹配出错,link=>{url} {ex.ToString()}");
                            }
                            if (!string.IsNullOrEmpty(answer.Answer))
                            {
                                question.Answers.Add(answer);
                            }
                        }
                        questions.Add(question);
                        if (question.Answers.Count == 0)
                            Logger.Error($"未匹配到答案,link=>{url}");
                    }
                    else
                    {
                        Logger.Error($"问题匹配出错,link=>{RequestUrl}");
                        continue;
                    }
                }
            }
            if (FilterCount > 0 && trlist.Count == FilterCount)
            {
                FilterCount = 0;
                return -1;
            }

            FilterCount = 0;
            if (questions.Count > 0)
            {
                var result = await SaveToDB(questions);
                if (!string.IsNullOrEmpty(result.Content))
                {
                    Logger.Error(result.Content);
                }
                return result.Count;
            }
            return 0;
        }

        protected async Task<(int Count, string Content)> SaveToDB(List<WD_Question> list)
        {
            return await dal.AddQuestions(list).ConfigureAwait(continueOnCapturedContext: false);
        }
    }
}
